using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using CR.Application.DTOs;
using CR.Application.Interfaces;
using CR.Domain.Entities;
using CR.ErrorCode;
using CR.Infrastructure;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace CR.Application.Services
{
    /// <summary>
    /// 产品检验报告服务实现
    /// </summary>
    public class ProductInspectionReportService : IProductInspectionReportService
    {
        private readonly IBaseRepository<ProductInspectionReport> _repository;
        private readonly IMapper _mapper;
        private readonly ILogger<ProductInspectionReportService> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="repository">仓储</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public ProductInspectionReportService(
            IBaseRepository<ProductInspectionReport> repository,
            IMapper mapper,
            ILogger<ProductInspectionReportService> logger)
        {
            _repository = repository;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 获取指定溯源码的所有检验报告
        /// </summary>
        /// <param name="traceabilityCode">溯源码</param>
        /// <returns>检验报告列表和操作结果</returns>
        public async Task<ApiResult<IEnumerable<ProductInspectionReportDTO>>> GetByTraceabilityCodeAsync(string traceabilityCode)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(traceabilityCode))
                {
                    return ApiResult<IEnumerable<ProductInspectionReportDTO>>.Fail(ApiEnums.BadRequest, "溯源码不能为空");
                }

                var reports = await _repository.FindAsync(r => 
                    r.TraceabilityCode == traceabilityCode && r.IsDeleted == 0);
                
                var reportDTOs = _mapper.Map<IEnumerable<ProductInspectionReportDTO>>(reports);
                return ApiResult<IEnumerable<ProductInspectionReportDTO>>.Success(reportDTOs);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取溯源码 {traceabilityCode} 的检验报告时出错");
                return ApiResult<IEnumerable<ProductInspectionReportDTO>>.Fail(ApiEnums.SystemError, $"获取检验报告失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 添加产品检验报告
        /// </summary>
        /// <param name="traceabilityCode">溯源码</param>
        /// <param name="file">报告图片文件</param>
        /// <param name="webRootPath">Web根目录路径</param>
        /// <returns>添加的报告和操作结果</returns>
        public async Task<ApiResult<ProductInspectionReportDTO>> AddReportAsync(string traceabilityCode, IFormFile file, string webRootPath)
        {
            try
            {
                // 验证溯源码
                if (string.IsNullOrWhiteSpace(traceabilityCode))
                {
                    return ApiResult<ProductInspectionReportDTO>.Fail(ApiEnums.BadRequest, "溯源码不能为空");
                }

                // 验证文件
                if (file == null || file.Length == 0)
                {
                    return ApiResult<ProductInspectionReportDTO>.Fail(ApiEnums.BadRequest, "没有提供文件");
                }

                // 验证文件类型
                var allowedTypes = new[] { "image/jpeg", "image/jpg", "image/png", "image/gif", "application/pdf" };
                if (!Array.Exists(allowedTypes, type => type == file.ContentType))
                {
                    return ApiResult<ProductInspectionReportDTO>.Fail(ApiEnums.BadRequest, "仅支持JPEG, JPG, PNG, GIF和PDF格式");
                }

                // 验证文件大小（限制为10MB）
                if (file.Length > 10 * 1024 * 1024)
                {
                    return ApiResult<ProductInspectionReportDTO>.Fail(ApiEnums.BadRequest, "文件大小不能超过10MB");
                }

                // 验证webRootPath不为空
                if (string.IsNullOrEmpty(webRootPath))
                {
                    return ApiResult<ProductInspectionReportDTO>.Fail(ApiEnums.SystemError, "Web根目录路径不能为空");
                }

                // 创建上传目录
                string uploadsFolder = Path.Combine(webRootPath, "uploads", "reports");
                
                // 确保目录存在
                if (!Directory.Exists(uploadsFolder))
                {
                    Directory.CreateDirectory(uploadsFolder);
                }

                // 生成唯一文件名
                string uniqueFileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(file.FileName);
                string filePath = Path.Combine(uploadsFolder, uniqueFileName);

                // 保存文件
                using (var fileStream = new FileStream(filePath, FileMode.Create))
                {
                    await file.CopyToAsync(fileStream);
                }

                // 构建文件URL
                string fileUrl = $"/uploads/reports/{uniqueFileName}";

                // 创建产品检验报告记录
                var report = new ProductInspectionReport
                {
                    TraceabilityCode = traceabilityCode,
                    ReportImagePath = fileUrl,
                    CreateTime = DateTime.Now
                };

                // 保存到数据库
                await _repository.AddAsync(report);

                var reportDTO = _mapper.Map<ProductInspectionReportDTO>(report);
                return ApiResult<ProductInspectionReportDTO>.Success(reportDTO, "检验报告上传成功");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"为溯源码 {traceabilityCode} 添加检验报告时出错");
                return ApiResult<ProductInspectionReportDTO>.Fail(ApiEnums.SystemError, $"添加检验报告失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 删除产品检验报告
        /// </summary>
        /// <param name="id">报告ID</param>
        /// <returns>操作结果</returns>
        public async Task<ApiResult> DeleteReportAsync(int id)
        {
            try
            {
                // 获取报告
                var report = await _repository.GetByIdAsync(id);
                if (report == null || report.IsDeleted == 1)
                {
                    return ApiResult.Fail(ApiEnums.NotFound, "检验报告不存在");
                }

                // 软删除报告
                report.IsDeleted = 1;
                report.UpdateTime = DateTime.Now;
                
                await _repository.UpdateAsync(report);
                
                return ApiResult.Success("检验报告删除成功");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"删除检验报告ID {id} 时出错");
                return ApiResult.Fail(ApiEnums.SystemError, $"删除检验报告失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取指定ID的检验报告
        /// </summary>
        /// <param name="id">报告ID</param>
        /// <returns>检验报告和操作结果</returns>
        public async Task<ApiResult<ProductInspectionReportDTO>> GetByIdAsync(int id)
        {
            try
            {
                var report = await _repository.GetByIdAsync(id);
                if (report == null || report.IsDeleted == 1)
                {
                    return ApiResult<ProductInspectionReportDTO>.Fail(ApiEnums.NotFound, "检验报告不存在");
                }

                var reportDTO = _mapper.Map<ProductInspectionReportDTO>(report);
                return ApiResult<ProductInspectionReportDTO>.Success(reportDTO);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取检验报告ID {id} 时出错");
                return ApiResult<ProductInspectionReportDTO>.Fail(ApiEnums.SystemError, $"获取检验报告失败: {ex.Message}");
            }
        }
    }
} 